import {
    request,
    AbstractBookCrawler,
    BasicBook,
    SearchBookResult,
    Book,
    BasicChapter,
    BookCrawlerTest,
    BookSource,
    getAbsPath
} from "../../common/common_node.js";

class BookCrawler extends AbstractBookCrawler {

    async searchBook(keyword, pageNum) {
        function getBoolList($) {
            const bookArr = [];
            const trArr = $("tbody tr");
            trArr.each(function (index, elem) {
                let tds = $(elem).find("td");
                let nameAndPath = tds.eq(0).find("a");
                if (!nameAndPath.length) {
                    return;
                }
                bookArr.push(new BasicBook({
                    name: nameAndPath.attr("title"),
                    author: tds.eq(1).text(),
                    path: nameAndPath.attr("href"),
                }));
            })
            return bookArr;
        }

        let url = `${this.source.searchBaseUrl}/plus/search.php?q=${encodeURIComponent(keyword)}`;
        const doc = await (await request(url, {
            deviceType: 'mobile',
        })).doc();
        const bookArr = getBoolList(doc);

        return new SearchBookResult({
            pageNum: 1,
            pages: 1,
            keyword: keyword,
            bookList: bookArr
        });
    }

    async bookDetails(path) {
        const $ = await (await request(this.source.bookBaseUrl + path)).doc();

        return new Book({
            name: $("meta[property='og:novel:book_name']").attr('content'),
            author: $("meta[property='og:novel:author']").attr('content'),
            path: path,
            intro: $('.book-detail').text(),
            coverUrl: this.source.bookBaseUrl + $("meta[property='og:image']").attr('content'),
            type: $("meta[property='og:novel:category']").attr('content'),
        });
    }

    async bookCatalog(path) {
        const $ = await (await request(this.source.bookBaseUrl + path)).doc();
        const chapters = $('#all-chapter .row a');
        let catalog = [];
        chapters.each(function (i, elem) {
            const item = $(elem);
            catalog.push(new BasicChapter({
                index: i,
                title: item.text(),
                path: item.attr("href")
            }));
        });
        return catalog;
    }

    async chapterContent(path) {
        const $ = await (await request(this.source.bookBaseUrl + path)).doc();
        let content = '';
        const pTags = $('#cont-body p');
        pTags.each(function (index) {
            content += $(this).text();
            // 如果不是最后一个p标签，则添加换行符
            if (index !== pTags.length - 1) {
                content += '\n';
            }
        });

        const page = $('.page');
        if (page.length > 0) {
            const liArr = page.first().find('li.active').nextAll('li');
            if (liArr.length > 0) {
                content += `\n${await this.chapterContent(getAbsPath(path, liArr.first().find('a').attr('href')))}`;
            }
        }
        return content;
    }
}

const source = {
    "id": "free_book_js/7",
    "name": "夜伴书屋",
    "portalUrl": "https://www.ybswu.com",
    "searchBaseUrl": "https://www.ybswu.com",
    "bookBaseUrl": "https://www.ybswu.com",
    "active": true
};

await new BookCrawlerTest(new BookCrawler(BookSource.createTestBookSource(source)), {
    enableSearch: true,
    keyword: "重生",
}).run();

